home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / filesyst / thsfs.tgz / thsfs.tar / thsfs / super.c < prev    next >
C/C++ Source or Header  |  1994-10-04  |  8KB  |  381 lines

  1. /*************************************************************
  2.  *                                                           *
  3.  *    ths  Filesystem                  04.10.94      V1.1    *
  4.  *                                                           *
  5.  *    Thomas Scheuermann     ths@ai-lab.fh-furtwangen.de     *
  6.  *                                                           *
  7.  *************************************************************/
  8.  
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/sched.h>
  12. #include <linux/errno.h>
  13. #include <linux/string.h>
  14. #include <linux/stat.h>
  15. #include <linux/mm.h>
  16. #include <linux/locks.h>
  17. #include <linux/fs.h>
  18. #include <linux/malloc.h>
  19.  
  20. #include <asm/system.h>
  21. #include <asm/segment.h>
  22. #include <asm/bitops.h>
  23.  
  24. #include "ths.h"
  25. #include "ths_i.h"
  26.  
  27. static struct super_operations ths_sops = { 
  28.         ths_read_inode,
  29.         NULL,
  30.         NULL,
  31.         NULL,
  32.         ths_put_super,
  33.         NULL,
  34.         ths_statfs,
  35.         NULL
  36. };
  37.  
  38.  
  39. /*
  40.  * Lesen des MSDOS-Bootblocks und Ausfuellen der
  41.  * super_block Struktur
  42.  */
  43.  
  44. struct super_block *ths_read_super(struct super_block *s, void *data, int silent)
  45. {
  46.     struct ths_sb_info *ths_sb;
  47.  
  48.     ths_sb = (struct ths_sb_info *)kmalloc(512,GFP_KERNEL);
  49.     s->u.generic_sbp = ths_sb;
  50.  
  51.     if(data==NULL)
  52.     {
  53.         ths_sb->art=0;            /* normales DOS */
  54.         return ths_read_super_normal(s,data,silent);
  55.     }
  56.     else
  57.     {
  58.         ths_sb->art=1;            /* DoubleSpace */
  59.         return ths_read_super_dblspace(s,data,silent);
  60.     }
  61. }
  62.  
  63.  
  64. /*
  65.  * Lesen des Super-Blocks fuer DoubleSpace-Laufwerke
  66.  */
  67.  
  68. struct super_block *ths_read_super_dblspace(struct super_block *s, void *data, int silent)
  69. {
  70.     struct buffer_head *bh;
  71.     struct ths_boot_sektor *bs;
  72.     struct dbl_boot_sektor *dbl;
  73.     struct ths_sb_info *ths_sb;
  74.     char *data1=NULL;
  75.     long RootStart;
  76.  
  77.     ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
  78.  
  79. #ifdef DEBUG
  80.     printk("DoubleSpace-Superblock\n");
  81. #endif
  82.  
  83.     lock_super(s);
  84.     bh = bread(s->s_dev,0,BLOCK_SIZE);
  85.  
  86.     if (bh == NULL)
  87.     {
  88.         s->s_dev = 0;
  89.         printk("ths bread failed\n");
  90.         unlock_super(s);
  91.         return NULL;
  92.     }
  93.     bs = (struct ths_boot_sektor *)bh->b_data;
  94.  
  95.     ths_sb->uFATStart = CHS(bs->ReservierteSektoren);
  96.     ths_sb->uDatenStart = CHS(bs->ReservierteSektoren) +
  97.                       (bs->AnzahlFats * CHS(bs->SektorenProFat)) +
  98.                       (CHS(bs->EintraegeRootverzeichnis) / 16);
  99.     ths_sb->uSektorenProCluster = bs->SektorenProCluster;
  100.     ths_sb->uAnzahlCluster = (short)(((CHS(bs->SektorenImVolume) ? CHS(bs->SektorenImVolume) :
  101.                             CHL(bs->SektorenImVolume2)) -
  102.                             CHS(bs->ReservierteSektoren) -
  103.                            (bs->AnzahlFats * CHS(bs->SektorenProFat)) -
  104.                            (CHS(bs->EintraegeRootverzeichnis) / 16)) /
  105.                            bs->SektorenProCluster);
  106.     ths_sb->uBitsProCluster = ths_sb->uAnzahlCluster < 4078 ? 12 : 16;
  107.     RootStart = CHS(bs->ReservierteSektoren) +
  108.                       (bs->AnzahlFats * CHS(bs->SektorenProFat));
  109.  
  110.  
  111.     ths_sb->StartCluster = findeStartCluster(s,RootStart,CHS(bs->EintraegeRootverzeichnis),data);
  112.     if(ths_sb->StartCluster == 0)
  113.     {
  114.         printk("CVF nicht gefunden !!\n");
  115.         brelse(bh);
  116.         unlock_super(s);
  117.         return NULL;
  118.     }
  119. #ifdef DEBUG
  120.     printk("StartCluster : %d\n",ths_sb->StartCluster);
  121. #endif
  122.  
  123.     unlock_super(s);
  124.  
  125.  
  126.     data1 = ths_uread(s,0,&bh);
  127.     bs = (struct ths_boot_sektor *)data1;
  128.     superfill(s,ths_sb,bs);
  129.  
  130.     dbl = (struct dbl_boot_sektor *)data1;
  131.  
  132.     ths_sb->BitFATStart = 1;
  133.  
  134.     ths_sb->MDFATStart = (long)CHS(dbl->MDFATStart)+1;
  135.  
  136.     ths_sb->BootStart = (long)CHS(dbl->res0);
  137.  
  138.     ths_sb->FatStart = (long)(CHS(dbl->res0)+CHS(dbl->ReservierteSektoren));
  139.  
  140.     ths_sb->RootStart = (long)(CHS(dbl->res0) + CHS(dbl->RootDirStart));
  141.  
  142.     ths_sb->DatenStart = (long)(CHS(dbl->res0) + CHS(dbl->DatenStart)+2);
  143.  
  144.     ths_sb->AnzahlCluster = ths_sb->AnzahlCluster*8;
  145.  
  146.     ths_sb->dcluster = CHS(dbl->ClusterStart);
  147.  
  148. #ifdef DEBUG
  149.     printk("BitFATStart : %ld\n",ths_sb->BitFATStart);
  150.     printk("MDFATStart = %ld\n",ths_sb->MDFATStart);
  151.     printk("BootStart : %ld\n",ths_sb->BootStart);
  152.     printk("FatStart : %ld\n",ths_sb->FatStart);
  153.     printk("RootDirStart = %ld\n",ths_sb->RootStart);
  154.     printk("DatenStart = %ld\n",ths_sb->DatenStart);
  155.     printk("Anzahl Cluster = %d\n",ths_sb->AnzahlCluster);
  156.     printk("dev : %d\n",s->s_dev);
  157. #endif
  158.  
  159.     brelse(bh);
  160.  
  161.     cvffill(s);
  162.     fatmem2(s);
  163.  
  164.     s->s_blocksize = BLOCK_SIZE;
  165.     s->s_blocksize_bits = 10;
  166.     s->s_op = &ths_sops;
  167.  
  168.     s->s_mounted = iget(s,1);
  169.  
  170.  
  171.     return s;
  172. }
  173.  
  174.  
  175. /*
  176.  * Lesen des Super-Blocks fuer normale DOS-Laufwerke
  177.  */
  178.  
  179. struct super_block *ths_read_super_normal(struct super_block *s, void *data, int silent)
  180. {
  181.     struct buffer_head *bh;
  182.     struct ths_boot_sektor *bs;
  183.     struct ths_sb_info *ths_sb;
  184.  
  185. #ifdef DEBUG
  186.     printk("read_super\n");
  187.     printk("Daten : %s\n",(char *)data);
  188. #endif
  189.  
  190.     /*
  191.      * Lesen des Bootblocks
  192.      */
  193.  
  194.     lock_super(s);
  195.     bh = bread(s->s_dev,0,BLOCK_SIZE);
  196.  
  197.     if (bh == NULL)
  198.     {
  199.         s->s_dev = 0;
  200.         printk("ths bread failed\n");
  201.         unlock_super(s);
  202.         return NULL;
  203.     }
  204.  
  205.     bs = (struct ths_boot_sektor *)bh->b_data;
  206.  
  207.     ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
  208.  
  209.  
  210. /*
  211.  * Fuellen der Struktur
  212.  */
  213.     superfill(s,ths_sb,bs);
  214.  
  215.     unlock_super(s);
  216.  
  217.     brelse(bh);
  218.  
  219.     fatmem2(s);
  220.  
  221.     s->s_blocksize = BLOCK_SIZE;
  222.     s->s_blocksize_bits = 10;
  223.     s->s_op = &ths_sops;
  224.  
  225.     s->s_mounted = iget(s,1);
  226.  
  227. #ifdef DEBUG
  228.     printk("dev : %d\n",s->s_dev);
  229. #endif
  230.  
  231.     return s;
  232. }
  233.  
  234.  
  235. /*
  236.  * Informationen aus dem Superblock extrahieren.
  237.  */
  238.  
  239. void superfill(struct super_block *s,struct ths_sb_info *ths_sb,struct ths_boot_sektor *bs)
  240. {
  241.     s->s_magic = THS_MAGIC;
  242.  
  243.     ths_sb->SektorenProCluster = bs->SektorenProCluster;
  244.  
  245.     ths_sb->SektorenProFat = CHS(bs->SektorenProFat);
  246.  
  247.     ths_sb->AnzahlCluster = (short)(((CHS(bs->SektorenImVolume) ? CHS(bs->SektorenImVolume) :
  248.                                 CHL(bs->SektorenImVolume2)) -
  249.                                 CHS(bs->ReservierteSektoren) -
  250.                                (bs->AnzahlFats * CHS(bs->SektorenProFat)) -
  251.                                (CHS(bs->EintraegeRootverzeichnis) / 16)) /
  252.                                bs->SektorenProCluster);
  253.  
  254.     ths_sb->BitsProCluster = ths_sb->AnzahlCluster < 4078 ? 12 : 16;
  255.  
  256.     ths_sb->FatStart = CHS(bs->ReservierteSektoren);
  257.  
  258.     ths_sb->RootMaxEintraege = CHS(bs->EintraegeRootverzeichnis);
  259.  
  260.     ths_sb->DatenStart = CHS(bs->ReservierteSektoren) +
  261.                           (bs->AnzahlFats * CHS(bs->SektorenProFat)) +
  262.                           (CHS(bs->EintraegeRootverzeichnis) / 16);
  263.  
  264.     ths_sb->RootStart = CHS(bs->ReservierteSektoren) +
  265.                           (bs->AnzahlFats * CHS(bs->SektorenProFat));
  266.  
  267. #ifdef DEBUG
  268.     printk("SektorenProCluster :%i\n",ths_sb->SektorenProCluster);
  269.     printk("SektorenProFat :%i\n",ths_sb->SektorenProFat);
  270.     printk("Sektoren1 : %d\n",CHS(bs->SektorenImVolume));
  271.     printk("Sektoren2 : %ld\n",CHL(bs->SektorenImVolume2));
  272.     printk("AnzahlCluster :%d\n",ths_sb->AnzahlCluster);
  273.     printk("BitsProCluster :%d\n",ths_sb->BitsProCluster);
  274.     printk("FatStart :%ld\n",ths_sb->FatStart);
  275.     printk("RootMaxEintraege :%d\n",ths_sb->RootMaxEintraege);
  276.     printk("DatenStart :%ld\n",ths_sb->DatenStart);
  277.     printk("RootStart :%ld\n",ths_sb->RootStart);
  278. #endif
  279. }
  280.  
  281.  
  282. /*
  283.  * Suche nach dem Startcluster des CVF
  284.  */
  285.  
  286. short findeStartCluster(struct super_block *s,long Rootdir, short Eintraege, char *name)
  287. {
  288.     int i,j;
  289.     char *data=NULL;
  290.     struct buffer_head *bh=NULL;
  291.     struct ths_dir *dir;
  292.  
  293.     for(j=0;name[j]!='\0';j++);
  294.  
  295. #ifdef DEBUG
  296.     printk("%s : %d\n",name,j);
  297. #endif
  298.  
  299.     for(i=0;i<Eintraege*32;)
  300.     {
  301.         if(!(i&0x1ff))
  302.         {
  303.             data = ths_uread_sektor(Rootdir+i/512,s->s_dev,&bh);
  304.         }
  305.         dir = (struct ths_dir *)&data[i%512];
  306.  
  307.  
  308.         if(vergleich(dir,(const char *)name,j))
  309.         {
  310.             brelse(bh);
  311.             return CHS(dir->cluster);
  312.         }
  313.         i+=32;
  314.         if(!(i&0x1ff))
  315.             brelse(bh);
  316.     }
  317.     return 0;
  318. }
  319.  
  320.  
  321. void ths_put_super(struct super_block *s)
  322. {
  323. #ifdef DEBUG
  324.     printk("put_super\n");
  325. #endif
  326.     lock_super(s);
  327.     fatfree(s);
  328.     cvffree(s);
  329.     kfree_s(s->u.generic_sbp,512);
  330.     s->s_dev=0;
  331.     unlock_super(s);
  332.     
  333.     return;
  334. }
  335.  
  336.  
  337. void ths_statfs(struct super_block *s, struct statfs *buf)
  338. {
  339.     struct ths_sb_info *ths_sb;
  340.     long i,j,k;
  341.     short *addr;
  342.  
  343. #ifdef DEBUG
  344.     printk("statfs\n");
  345. #endif
  346.  
  347.     ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
  348.     put_fs_long(THS_MAGIC, &buf->f_type);
  349.     put_fs_long(1024, &buf->f_bsize);
  350.     put_fs_long(ths_sb->AnzahlCluster*ths_sb->SektorenProCluster/2, &buf->f_blocks);
  351.  
  352.     j=0;
  353.  
  354. /*
  355.  * k wird auf 2 gesetzt, da die ersten beide Eintraege
  356.  * der FAT keine Cluster-Zeiger sind.
  357.  */
  358.     k=2;
  359.     addr=ths_sb->fat[0];
  360.     for (i=0;i<ths_sb->AnzahlCluster;i++)
  361.     {
  362.         if(addr[k]==0)
  363.             j++;
  364.         k++;
  365.         if(k==2048)
  366.         {
  367.             k=0;
  368.             addr=ths_sb->fat[(i+3)/2048];
  369.         }
  370.     }
  371.     j*=ths_sb->SektorenProCluster;
  372.     j/=2;
  373. #ifdef DEBUG
  374.     printk("frei : %ld\n",j);
  375. #endif
  376.     put_fs_long(j, &buf->f_bfree);
  377.     put_fs_long(j, &buf->f_bavail);
  378. }
  379.  
  380.  
  381.